<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket本地测试工具</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: Arial, sans-serif;
            background-color: #f5f5f5;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            padding: 20px;
        }

        .header {
            text-align: center;
            margin-bottom: 30px;
            color: #333;
        }

        .section {
            margin-bottom: 20px;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }

        .section h3 {
            margin-bottom: 10px;
            color: #555;
        }

        .form-group {
            margin-bottom: 15px;
        }

        label {
            display: inline-block;
            width: 100px;
            font-weight: bold;
        }

        input[type="text"], input[type="number"], textarea {
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            width: 300px;
        }

        button {
            padding: 8px 16px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
        }

        button:hover {
            background-color: #0056b3;
        }

        button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }

        .status {
            padding: 5px 10px;
            border-radius: 3px;
            font-weight: bold;
        }

        .status.connected {
            background-color: #d4edda;
            color: #155724;
        }

        .status.disconnected {
            background-color: #f8d7da;
            color: #721c24;
        }

        .status.connecting {
            background-color: #fff3cd;
            color: #856404;
        }

        .message-area {
            height: 200px;
            overflow-y: auto;
            border: 1px solid #ddd;
            padding: 10px;
            background-color: #f9f9f9;
            font-family: monospace;
            font-size: 12px;
        }

        .message-item {
            margin-bottom: 5px;
            padding: 2px 0;
        }

        .message-time {
            color: #666;
            margin-right: 10px;
        }

        .message-content {
            color: #333;
        }

        .message-received {
            color: #28a745;
        }

        .message-sent {
            color: #007bff;
        }

        .message-error {
            color: #dc3545;
        }

        .two-column {
            display: flex;
            gap: 20px;
        }

        .column {
            flex: 1;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1>WebSocket 本地测试工具</h1>
        <p>本地化WebSocket连接调试测试工具</p>
    </div>

    <div class="section">
        <h3>服务器配置</h3>
        <div class="form-group">
            <label>状态:</label>
            <span id="connectionStatus" class="status disconnected">尚未创建</span>
        </div>
        <div class="form-group">
            <label>服务地址:</label>
            <input type="text" id="serverUrl" placeholder="ws://localhost:8080" value="ws://echo.websocket.org">
            <button id="connectBtn">开启连接</button>
            <button id="disconnectBtn" disabled>断开连接</button>
        </div>
    </div>

    <div class="two-column">
        <div class="column">
            <div class="section">
                <h3>发包设置</h3>
                <div class="form-group">
                    <label>定时发送:</label>
                    每隔 <input type="number" id="intervalTime" value="5" min="1" max="3600" style="width: 80px;"> 秒发送内容
                    <button id="startSendBtn">开始发送</button>
                    <button id="stopSendBtn" disabled>停止发送</button>
                </div>
                <div class="form-group">
                    <label>发送内容:</label><br>
                    <textarea id="sendContent" rows="3" placeholder="请输入要发送的内容"></textarea>
                </div>
                <div class="form-group">
                    <button id="sendBtn">发送到服务端</button>
                    <button id="clearSendBtn">清空输入</button>
                </div>
            </div>
        </div>

        <div class="column">
            <div class="section">
                <h3>消息记录</h3>
                <div class="form-group">
                    <button id="clearReceiveBtn">清空消息</button>
                    <button id="pauseReceiveBtn">暂停接收</button>
                    <button id="resumeReceiveBtn" disabled>恢复接收</button>
                    <label>
                        <input type="checkbox" id="jsonDecodeChk"> JSON解码
                    </label>
                </div>
                <div id="messageArea" class="message-area"></div>
            </div>
        </div>
    </div>

    <div class="section">
        <h3>调试消息</h3>
        <div id="debugArea" class="message-area"></div>
    </div>
</div>

<script>
    class WebSocketTester {
        constructor() {
            this.ws = null;
            this.isConnected = false;
            this.intervalId = null;
            this.isPaused = false;
            this.initializeElements();
            this.bindEvents();
            this.addDebugMessage('初始化完成');
        }

        initializeElements() {
            this.elements = {
                serverUrl: document.getElementById('serverUrl'),
                connectionStatus: document.getElementById('connectionStatus'),
                connectBtn: document.getElementById('connectBtn'),
                disconnectBtn: document.getElementById('disconnectBtn'),
                sendContent: document.getElementById('sendContent'),
                sendBtn: document.getElementById('sendBtn'),
                clearSendBtn: document.getElementById('clearSendBtn'),
                intervalTime: document.getElementById('intervalTime'),
                startSendBtn: document.getElementById('startSendBtn'),
                stopSendBtn: document.getElementById('stopSendBtn'),
                messageArea: document.getElementById('messageArea'),
                debugArea: document.getElementById('debugArea'),
                clearReceiveBtn: document.getElementById('clearReceiveBtn'),
                pauseReceiveBtn: document.getElementById('pauseReceiveBtn'),
                resumeReceiveBtn: document.getElementById('resumeReceiveBtn'),
                jsonDecodeChk: document.getElementById('jsonDecodeChk')
            };
        }

        bindEvents() {
            this.elements.connectBtn.addEventListener('click', () => this.connect());
            this.elements.disconnectBtn.addEventListener('click', () => this.disconnect());
            this.elements.sendBtn.addEventListener('click', () => this.sendMessage());
            this.elements.clearSendBtn.addEventListener('click', () => this.clearSendContent());
            this.elements.startSendBtn.addEventListener('click', () => this.startIntervalSend());
            this.elements.stopSendBtn.addEventListener('click', () => this.stopIntervalSend());
            this.elements.clearReceiveBtn.addEventListener('click', () => this.clearReceiveMessages());
            this.elements.pauseReceiveBtn.addEventListener('click', () => this.pauseReceive());
            this.elements.resumeReceiveBtn.addEventListener('click', () => this.resumeReceive());

            // 回车发送消息
            this.elements.sendContent.addEventListener('keypress', (e) => {
                if (e.key === 'Enter' && e.ctrlKey) {
                    this.sendMessage();
                }
            });
        }

        connect() {
            const url = this.elements.serverUrl.value.trim();
            if (!url) {
                this.addDebugMessage('请输入服务器地址', 'error');
                return;
            }

            try {
                this.updateConnectionStatus('connecting', '连接中...');
                this.addDebugMessage(`正在连接到: ${url}`);

                this.ws = new WebSocket(url);

                this.ws.onopen = () => {
                    this.isConnected = true;
                    this.updateConnectionStatus('connected', '已连接');
                    this.addDebugMessage('WebSocket连接成功');
                    this.updateButtonStates();
                };

                this.ws.onmessage = (event) => {
                    if (!this.isPaused) {
                        this.addReceiveMessage(event.data);
                    }
                };

                this.ws.onclose = (event) => {
                    this.isConnected = false;
                    this.updateConnectionStatus('disconnected', '已断开');
                    this.addDebugMessage(`连接关闭: ${event.code} - ${event.reason || '正常关闭'}`);
                    this.updateButtonStates();
                    this.stopIntervalSend();
                };

                this.ws.onerror = (error) => {
                    this.addDebugMessage('WebSocket连接错误', 'error');
                    this.updateConnectionStatus('disconnected', '连接失败');
                };

            } catch (error) {
                this.addDebugMessage(`创建 WebSocket 对象失败 请检查服务器地址: ${error.message}`, 'error');
                this.updateConnectionStatus('disconnected', '连接失败');
            }
        }

        disconnect() {
            if (this.ws) {
                this.ws.close();
                this.ws = null;
            }
            this.stopIntervalSend();
        }

        sendMessage() {
            if (!this.isConnected || !this.ws) {
                this.addDebugMessage('未连接到服务器', 'error');
                return;
            }

            const content = this.elements.sendContent.value;
            if (!content.trim()) {
                this.addDebugMessage('发送内容不能为空', 'error');
                return;
            }

            try {
                this.ws.send(content);
                this.addDebugMessage(`发送消息: ${content.substring(0, 100)}${content.length > 100 ? '...' : ''}`, 'sent');
            } catch (error) {
                this.addDebugMessage(`发送失败: ${error.message}`, 'error');
            }
        }

        clearSendContent() {
            this.elements.sendContent.value = '';
        }

        startIntervalSend() {
            if (!this.isConnected) {
                this.addDebugMessage('未连接到服务器', 'error');
                return;
            }

            const interval = parseInt(this.elements.intervalTime.value) * 1000;
            if (interval < 1000) {
                this.addDebugMessage('发送间隔不能小于1秒', 'error');
                return;
            }

            this.intervalId = setInterval(() => {
                this.sendMessage();
            }, interval);

            this.elements.startSendBtn.disabled = true;
            this.elements.stopSendBtn.disabled = false;
            this.addDebugMessage(`开始定时发送，间隔: ${interval/1000}秒`);
        }

        stopIntervalSend() {
            if (this.intervalId) {
                clearInterval(this.intervalId);
                this.intervalId = null;
            }
            this.elements.startSendBtn.disabled = false;
            this.elements.stopSendBtn.disabled = true;
            this.addDebugMessage('停止定时发送');
        }

        addReceiveMessage(data) {
            let displayData = data;
            if (this.elements.jsonDecodeChk.checked) {
                try {
                    const parsed = JSON.parse(data);
                    displayData = JSON.stringify(parsed, null, 2);
                } catch (e) {
                    // 如果不是JSON格式，保持原样
                }
            }
            this.addMessage(this.elements.messageArea, `收到: ${displayData}`, 'received');
        }

        addDebugMessage(message, type = 'info') {
            this.addMessage(this.elements.debugArea, message, type);
        }

        addMessage(container, message, type = 'info') {
            const messageDiv = document.createElement('div');
            messageDiv.className = 'message-item';

            const time = new Date().toLocaleTimeString();
            messageDiv.innerHTML = `
                    <span class="message-time">${time}</span>
                    <span class="message-content message-${type}">${message}</span>
                `;

            container.appendChild(messageDiv);
            container.scrollTop = container.scrollHeight;

            // 限制消息数量，避免内存占用过多
            if (container.children.length > 1000) {
                container.removeChild(container.firstChild);
            }
        }

        clearReceiveMessages() {
            this.elements.messageArea.innerHTML = '';
        }

        pauseReceive() {
            this.isPaused = true;
            this.elements.pauseReceiveBtn.disabled = true;
            this.elements.resumeReceiveBtn.disabled = false;
            this.addDebugMessage('暂停接收消息');
        }

        resumeReceive() {
            this.isPaused = false;
            this.elements.pauseReceiveBtn.disabled = false;
            this.elements.resumeReceiveBtn.disabled = true;
            this.addDebugMessage('恢复接收消息');
        }

        updateConnectionStatus(status, text) {
            this.elements.connectionStatus.className = `status ${status}`;
            this.elements.connectionStatus.textContent = text;
        }

        updateButtonStates() {
            this.elements.connectBtn.disabled = this.isConnected;
            this.elements.disconnectBtn.disabled = !this.isConnected;
            this.elements.sendBtn.disabled = !this.isConnected;
        }
    }

    // 初始化工具
    document.addEventListener('DOMContentLoaded', () => {
        new WebSocketTester();
    });
</script>
</body>
</html>